package net.googlecode.myshenko.Task4;


import java.util.StringTokenizer;

/**
 * Formate strings
 *
 *@author Vitalii Myshenko <a href="mailto:vitalii.myshenko@gmail.com">
 *
 * @since 5.04.11
 */
public class StringFormater {


    private String delimiters; //used to delimit sentence
    private boolean showDelimiters; //if true delimiters will be returned as part of word


    /**
     * Default constructor. Set default delimiters and their appearence
     */
    public StringFormater() {
        showDelimiters = false;
        delimiters = " \t\n";
    }

    /**
     * Capitalise first letter of word
     *
     * @param word word to be changed
     *
     * @return changed word
     */
    private String capitalise(String word){
       char ch = word.charAt(0);
       return Character.toUpperCase(ch) + word.substring(1);
    }

    /**
     * Capitalise first letter of every word in sentence
     *
     * @param sentence sentence to be changed
     *
     * @return string with all words capitalised
     */
    public String capitaliseAll(String sentence) {
        StringBuffer stringBuffer = new StringBuffer();
        StringTokenizer tokenizer = new StringTokenizer(sentence, delimiters, showDelimiters);

        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            token = this.capitalise(token);
            stringBuffer = stringBuffer.append(token).append(" ");
        }
        String capitalisedSentence = stringBuffer.toString();

        Logger.log("Capitalise first letter of all words in sentence");

        return capitalisedSentence;
    }

    /**
     * Replace defined chars in word
     *
     * @param word word to be changed
     * @param oldChar char to be changed
     * @param newChar char that will change oldChar
     * @return changed word
     */
    private String replaceCharsInWord(String word, String oldChar, String newChar){
        word = word.replaceAll(oldChar.toLowerCase(), newChar);
        word = word.replaceAll(oldChar.toUpperCase(), newChar);
        return word;
    }

    /**
     * Replace letter in whole sentence ignoring their case
     *
     * @param string sentence to be changed
     * @param oldChar char to be changed
     * @param newChar char that will change oldChar
     * @return changed sentence
     */
    public String replaceLetterIgnoreCase(String string, String oldChar, String newChar) {
        String normalString = this.standardSentence(string);
        StringTokenizer tokenizer = new StringTokenizer(normalString, delimiters, showDelimiters);
        StringBuffer stringBuffer = new StringBuffer();
        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            String replacedWord = this.replaceCharsInWord(token, oldChar, newChar);
            stringBuffer.append(replacedWord).append(" ");
        }
        Logger.log("replace letter " + oldChar + " to " + newChar);

        return stringBuffer.toString();
    }

    /**
     * Reverse letters in word
     *
     * @param word word to be reversed
     * @return reversed word
     */
    private String reverseWord(String word){
        StringBuilder stringBuilder = new StringBuilder(word);
        return stringBuilder.reverse().toString();
    }

    /**
     * Reverse all words in sentence
     *
     * @param string sentence to be reversed
     * @return reversed sentence
     */
    public String reverseAll(String string) {
        String normalString = this.standardSentence(string);
        StringBuffer stringBuffer = new StringBuffer();
        StringTokenizer tokenizer = new StringTokenizer(normalString, delimiters, showDelimiters);

        while (tokenizer.hasMoreTokens()) {

            String token = tokenizer.nextToken();
            if (token.endsWith(",")){
                String word = token.substring(0, token.length() - 1);
                String result = this.reverseWord(word);
                stringBuffer.append(result + "," + " ");
            } else {
                stringBuffer.append(this.reverseWord(token) + " ");
            }

        }
        Logger.log("reverse sequence of characters in the word");

        return stringBuffer.toString();
    }

    /**
     * Modify sentence to standard view:
     *                                  put all letters but first to lover case
     *                                  delete spaces before and after sentence
     *
     * @param string sentence to be normalised
     * @return normalised sentence
     */
    private String standardSentence(String string){
        StringBuffer stringBuffer = new StringBuffer();

        string = (string.trim()).toLowerCase();
        string = capitalise(string);

        StringTokenizer tokenizer = new StringTokenizer(string, delimiters, showDelimiters);

        while (tokenizer.hasMoreTokens()) {
            stringBuffer = stringBuffer.append(tokenizer.nextToken()).append(" ");
        }
        return stringBuffer.toString();
    }

    /**
     * Cast sentence to standard view:
     *                                  put all letters but first to lover case
     *                                  delete spaces before and after sentence
     *
     * @param string sentence to be normalised
     * @return normalised sentence
     */
    public String toStandardView(String string) {
        Logger.log("reduce the sentence to standard view");
        return this.standardSentence(string);
    }

    /**
     * Add user defined date to the end of sentence
     *
     * @param string string to which date should be added
     * @param shift define number of days to be added to current date
     * @return sentence with date
     */
    public String addMyDate(String string, int shift){
        DateFormater dateFormater = new DateFormater();
        String standardString = this.standardSentence(string);
        Logger.log("add date that " + shift + " days earlier");

        return standardString + dateFormater.calculateDate(shift);

    }
}
